package com.ht.aems.fesmodel.persist;

import com.ht.aems.dbservice.ConnectionFactory;
import com.ht.aems.dbservice.SqlExecutor;
import com.ht.aems.fesmodel.FesPersistence;
import com.ht.aems.fesmodel.data.MeasurePoint;
import com.ht.aems.fesmodel.data.YCData;
import com.ht.aems.fesmodel.data.YXData;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Dong Shufeng
 *         Date: 2010-5-12
 */
public class RtMeasureHandler_SQL {
    private static Logger log = Logger.getLogger(RtMeasureHandler_SQL.class);
    String database;

    public boolean saveYC(YCData yc) {
        return saveYCs(new YCData[]{yc});
    }

    public boolean saveYCs(YCData[] ycs) {
        List<String> batch = new ArrayList<String>();
        Connection conn = database != null ? ConnectionFactory.createConnection(database) : ConnectionFactory.createConnection();
        if (conn == null) {
            log.info("Connection can not be built, save yc failed ...");
            return false;
        }
        log.info("Start save yc ...");
        for (YCData yc : ycs) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(yc.getTimestamp());
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DAY_OF_MONTH);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            for (int i = 0; i < yc.getData().length; i++) {
                int nid = MeasurePoint.getNID(yc.getRemoteUnitId(), yc.getYcBit()[i]);
                if (isExist(FesPersistence.TABLE_ALG, nid, conn)) {
                    batch.add("update " + FesPersistence.TABLE_ALG + " set fEng=" + yc.getData()[i] + ",nYear=" + year + ",nMonth=" + month +
                            ",nDay=" + day + ",nHour=" + hour + ",nMinute=" + minute + ",nSecond=" + second +
                            " where nRtu=" + yc.getRemoteUnitId() + " and nPnt=" + yc.getYcBit()[i]);
                } else {
                    batch.add("insert into " + FesPersistence.TABLE_ALG + " (nid,nRtu,nPnt,fEng,nYear,nMonth,nDay,nHour,nMinute,nSecond) values " +
                            "(" + nid + "," + yc.getRemoteUnitId() + "," + yc.getYcBit()[i] + "," + yc.getData()[i] + "," +
                            year + "," + month + "," + day + "," + hour + "," + minute + "," + second + ")");
                }
            }
        }
        if (database != null) {
            if (SqlExecutor.executeBatch(conn, batch.toArray(new String[]{}), false)) {
                log.info("save yc success ...");
                return true;
            } else {
                log.info("save yc failed ...");
                return false;
            }
        } else {
            log.info("save yc faile because database name not is exist ...");
            return false;
        }
    }

    public boolean updateYCs(YCData[] ycs) {
        List<String> batch = new ArrayList<String>();
        Connection conn = database != null ? ConnectionFactory.createConnection(database) : ConnectionFactory.createConnection();
        if (conn == null) {
            log.info("Connection can not be built, save yc failed ...");
            return false;
        }
        log.info("Start save yc ...");
        for (YCData yc : ycs) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(yc.getTimestamp());
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DAY_OF_MONTH);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            for (int i = 0; i < yc.getData().length; i++) {
                int nid = MeasurePoint.getNID(yc.getRemoteUnitId(), yc.getYcBit()[i]);
                batch.add("update " + FesPersistence.TABLE_ALG + " set fEng=" + yc.getData()[i] + ",nYear=" + year + ",nMonth=" + month +
                        ",nDay=" + day + ",nHour=" + hour + ",nMinute=" + minute + ",nSecond=" + second +
                        " where nRtu=" + yc.getRemoteUnitId() + " and nPnt=" + yc.getYcBit()[i]);
            }
        }
        if (database != null) {
            if (SqlExecutor.executeBatch(conn, batch.toArray(new String[]{}), false)) {
                log.info("save yc success ...");
                return true;
            } else {
                log.info("save yc failed ...");
                return false;
            }
        } else {
            log.info("save yc faile because database name not is exist ...");
            return false;
        }
    }

    public boolean saveYX(YXData yx) {
        return saveYXs(new YXData[]{yx});
    }

    private boolean isExist(String table, int nid, Connection conn) {
        String sql = "select count(1) from " + table + " where nid = " + nid;
        Statement stm = null;
        ResultSet r = null;
        boolean result = false;
        try {
            stm = conn.createStatement();
            r = stm.executeQuery(sql);
            if (r.next())
                result = r.getInt(1) >= 1;
        } catch (SQLException e) {
            log.warn("<MeasSqlPersist> Exception:" + e);
            result = false;
        } finally {
            try {
                if (r != null)
                    r.close();
                if (stm != null)
                    stm.close();
            } catch (SQLException e) {
                log.warn(e);
            }
        }
        return result;
    }

    public boolean saveYXs(YXData[] yxs) {
        List<String> batch = new ArrayList<String>();
        Connection conn = database != null ? ConnectionFactory.createConnection(database) : ConnectionFactory.createConnection();
        if (conn == null) {
            log.info("Connection can not be built, save yx failed ...");
            return false;
        }
        log.info("Start save yx ...");
        for (YXData yx : yxs) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(yx.getTimestamp());
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DAY_OF_MONTH);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            for (int i = 0; i < yx.getData().length; i++) {
                int nid = MeasurePoint.getNID(yx.getRemoteUnitId(), yx.getYxBit()[i]);
                if (isExist(FesPersistence.TABLE_DIS, nid, conn)) {
                    batch.add("update " + FesPersistence.TABLE_DIS + " set nValue = " + yx.getData()[i] +
                            ",nYear=" + year + ",nMonth=" + month + ",nDay=" + day + ",nHour=" + hour + ",nMinute=" + minute + ",nSecond=" + second +
                            " where nRtu= " + yx.getRemoteUnitId() + " and nPnt=" + yx.getYxBit()[i]);
                } else {
                    batch.add("insert into " + FesPersistence.TABLE_DIS + "(nid,nRtu,nPnt,nValue,nYear,nMonth,nDay,nHour,nMinute,nSecond) values " +
                            "(" + nid + "," + yx.getRemoteUnitId() + "," + yx.getYxBit()[i] + "," + yx.getData()[i] + "," +
                            year + "," + month + "," + day + "," + hour + "," + minute + "," + second + ")");
                }
            }
        }
        if (SqlExecutor.executeBatch(conn, batch.toArray(new String[]{}), false)) {
            log.info("save yx success ...");
            return true;
        } else {
            log.info("save yx failed ...");
            return false;
        }
    }
    public boolean updateYXs(YXData[] yxs) {
        List<String> batch = new ArrayList<String>();
        Connection conn = database != null ? ConnectionFactory.createConnection(database) : ConnectionFactory.createConnection();
        if (conn == null) {
            log.info("Connection can not be built, save yx failed ...");
            return false;
        }
        log.info("Start upate yx ...");
        for (YXData yx : yxs) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(yx.getTimestamp());
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int day = c.get(Calendar.DAY_OF_MONTH);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            for (int i = 0; i < yx.getData().length; i++) {
                int nid = MeasurePoint.getNID(yx.getRemoteUnitId(), yx.getYxBit()[i]);
                batch.add("update " + FesPersistence.TABLE_DIS + " set nValue = " + yx.getData()[i] +
                        ",nYear=" + year + ",nMonth=" + month + ",nDay=" + day + ",nHour=" + hour + ",nMinute=" + minute + ",nSecond=" + second +
                        " where nRtu= " + yx.getRemoteUnitId() + " and nPnt=" + yx.getYxBit()[i]);
            }
        }
        if (SqlExecutor.executeBatch(conn, batch.toArray(new String[]{}), false)) {
            log.info("upate yx success ...");
            return true;
        } else {
            log.info("update yx failed ...");
            return false;
        }
    }


    public Map<Integer, Integer> getAnalogValues(int[] nids) {
        Map<Integer, Integer> result = new HashMap<Integer, Integer>();
        if (nids == null || nids.length < 1)
            return result;
        int index = 0;
        String sql = "select nId,nValue from " + FesPersistence.TABLE_DIS + " where ";
        for (int i = 0; i < nids.length; i++) {
            if (nids[i] != -1) {
                index++;
                if (index > 1)
                    sql += (" or nId=" + nids[i]);
                else
                    sql += ("nId=" + nids[i] + " ");
            }
        }
        System.out.println("##" + sql);
        Connection conn = ConnectionFactory.createConnection();
        Statement sm = null;
        ResultSet rs = null;
        try {
            if (conn != null) {
                sm = conn.createStatement();
                rs = sm.executeQuery(sql);
                while (rs.next())
                    result.put(rs.getInt("nId"), rs.getInt("nValue"));
                rs.close();
                sm.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) rs.close();
                if (sm != null) sm.close();
            } catch (Exception e) {
                log.warn("<MeasSqlPersist> Exception:" + e);
            }
            SqlExecutor.close(conn);
        }
        return result;
    }

    public YCData getRealtimeYC(int rtuId) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public double getRealtimeYCValue(int pointId) {
        return 0;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public double getRealtimeYCValue(int rtuId, int pointNum) {
        return 0;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public YXData getRealtimeYX(int rtuId) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public int getRealtimeYXValue(int pointId) {
        return 0;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public int getRealtimeYXValue(int rtuId, int pointNum) {
        return 0;  //To change body of implemented methods use File | Settings | File Templates.
    }

    /* (non-Javadoc)
      * @see com.ht.aems.fesmodel.persist.RtMeasureHandler#updateYC(com.ht.aems.fesmodel.data.YCData)
      */
    public boolean updateYC(YCData yc) {
         return updateYCs(new YCData[] {yc});
    }

    /* (non-Javadoc)

      * @see com.ht.aems.fesmodel.persist.RtMeasureHandler#updateYX(com.ht.aems.fesmodel.data.YXData)
      */
    public boolean updateYX(YXData yx) {
         return updateYXs(new YXData[] {yx});
    }
}
